home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
SourceCode
/
KeyDownBrowser
/
KeyDownBrowser.m
< prev
next >
Wrap
Text File
|
1992-12-19
|
10KB
|
386 lines
//---------------------------------------------------------------------------------------------------------
//
// KeyDownBrowser
//
// Inherits From: NXBrowser
//
// Declared In: KeyDownBrowser.h
//
// Disclaimer
//
// You may freely copy, distribute and reuse this software and its
// associated documentation. I disclaim any warranty of any kind,
// expressed or implied, as to its fitness for any particular use.
//
//---------------------------------------------------------------------------------------------------------
#import "KeyDownBrowser.h"
#import "KeyDownMatrix.h"
#define RETURN 13
#define LEFTARROW 172
#define UPARROW 173
#define RIGHTARROW 174
#define DOWNARROW 175
#define CHUNK 64
@implementation KeyDownBrowser
//---------------------------------------------------------------------------------------------------------
// Timed Entry Methods (Private)
//---------------------------------------------------------------------------------------------------------
void Search (timedEntry, now, self)
DPSTimedEntry timedEntry;
double now;
void* self;
{
[(id)self perform: @selector (_search)];
}
- _addTimedEntry
{
timedEntry = DPSAddTimedEntry (inputTimeOut, Search, (void*) self, NX_MODALRESPTHRESHOLD);
NXPing();
return self;
}
- _removeTimedEntry
{
if ( ! timedEntry) return self;
DPSRemoveTimedEntry (timedEntry);
timedEntry = 0;
return self;
}
//---------------------------------------------------------------------------------------------------------
// Miscellaneous Methods (Private)
//---------------------------------------------------------------------------------------------------------
- _chunk
{
// Allocate memory for input buffer.
if ( ! searchString)
searchString = NX_MALLOC (searchString, char, CHUNK);
else
searchString = NX_REALLOC (searchString, char, strlen(searchString) + CHUNK);
if ( ! searchString) NXLogError ("Out of Memory in _chunk!");
return self;
}
- _selectCellInRow:(int)aRow ofMatrix:aMatrix andDoClick:(BOOL)doClick
{
[aMatrix selectCellAt: aRow :0];
[aMatrix scrollCellToVisible: aRow :0];
if (doClick) [self doClick: aMatrix];
return self;
}
//---------------------------------------------------------------------------------------------------------
// Search Methods (Private)
//---------------------------------------------------------------------------------------------------------
- (int) _searchColumn
{
// If there is no selection within the browser, return column 0. If there are multiple selections
// return the current selected column. If there is 1 selection, then if it is a leaf, return the
// current selected column. If it is a branch, return the current selected column + 1.
id selectedCellList;
int searchColumn = [self selectedColumn];
if (searchColumn < 0) return 0;
if ([self isMultipleSelectionEnabled])
{
selectedCellList = [self getSelectedCells: nil];
if ([selectedCellList count] == 1)
if ([[selectedCellList objectAt: 0] isLeaf] == NO)
searchColumn++;
[selectedCellList free];
return searchColumn;
}
if ([self selectedCell])
if ([[self selectedCell] isLeaf] == NO) searchColumn++;
return searchColumn;
}
- _search
{
// Searches current search column for first occurrence of searchString.
int iterator;
int searchColumn = [self _searchColumn];
id matrix = [self matrixInColumn: searchColumn];
id currentCell;
BOOL found = NO;
[self _removeTimedEntry];
for (iterator = 0; iterator < [matrix numRows]; iterator++)
{
currentCell = [matrix cellAt: iterator :0];
if (NXOrderStrings([currentCell stringValue], searchString,
wantsCaseSensitiveSearch, strlen (searchString), NULL) == 0)
{
[matrix selectCellAt: -1 :-1];
[self _selectCellInRow:iterator ofMatrix:matrix andDoClick:YES];
found = YES;
break;
}
}
if (! found) NXBeep();
memset (searchString, 0, strlen (searchString));
return self;
}
//---------------------------------------------------------------------------------------------------------
// Key Down Methods (Private)
//---------------------------------------------------------------------------------------------------------
- _upArrow: (NXEvent *) theEvent
{
id matrix;
int selectedRow;
int selectedColumn = [self selectedColumn];
if (selectedColumn == -1) return self;
matrix = [self matrixInColumn:selectedColumn];
selectedRow = [matrix selectedRow] - 1;
if (selectedRow < 0) selectedRow = 0;
[self _selectCellInRow:selectedRow ofMatrix:matrix andDoClick:YES];
return self;
}
- _downArrow: (NXEvent *) theEvent
{
id matrix;
int selectedRow;
int selectedColumn = [self selectedColumn];
if (selectedColumn == -1) return self;
matrix = [self matrixInColumn: selectedColumn];
selectedRow = [matrix selectedRow] + 1;
if (selectedRow > [matrix numRows] - 1) selectedRow = [matrix numRows] - 1;
[self _selectCellInRow:selectedRow ofMatrix:matrix andDoClick:YES];
return self;
}
- _leftArrow: (NXEvent *) theEvent
{
id matrix;
int selectedColumn = [self selectedColumn];
if (selectedColumn == -1) return self;
matrix = [self matrixInColumn: selectedColumn];
[self setLastColumn: selectedColumn];
[matrix selectCellAt: -1 :-1];
[matrix sendAction:action to:target];
if (selectedColumn == 0) return self;
selectedColumn -= 1;
matrix = [self matrixInColumn: selectedColumn];
if ([self firstVisibleColumn] > selectedColumn) [self scrollColumnsRightBy: 1];
[matrix scrollCellToVisible: [matrix selectedRow] :[matrix selectedCol]];
return self;
}
- _rightArrow: (NXEvent *) theEvent
{
id matrix = [self matrixInColumn: ([self selectedColumn] + 1)];
if (! matrix) return self;
[self _selectCellInRow:0 ofMatrix:matrix andDoClick:YES];
return self;
}
- _return: (NXEvent *) theEvent
{
int selectedColumn = [self selectedColumn];
if (selectedColumn == -1) return self;
[self doDoubleClick: [self matrixInColumn:selectedColumn]];
return self;
}
//---------------------------------------------------------------------------------------------------------
// Initialization
//---------------------------------------------------------------------------------------------------------
- initFrame: (const NXRect *) frameRect
{
// Give it default IB characteristics, set the Matrix class, enable keys.
[super initFrame: frameRect];
[self setMatrixClass: [KeyDownMatrix class]];
[self separateColumns: YES];
[self setHorizontalScrollerEnabled: YES];
[self setEmptySelectionEnabled: YES];
[self setTitle: "KeyDownBrowser" ofColumn: 0];
[self acceptArrowKeys:YES andSendActionMessages:YES];
[self wantsCaseSensitiveSearch: NO];
[self inputTimeOut: 0.5];
[self _chunk];
memset (searchString, 0, CHUNK);
return self;
}
- free
{
[self _removeTimedEntry];
if (searchString) free (searchString);
return [super free];
}
//---------------------------------------------------------------------------------------------------------
// Accessors
//---------------------------------------------------------------------------------------------------------
- wantsCaseSensitiveSearch: (BOOL) aFlag
{
wantsCaseSensitiveSearch = aFlag;
return self;
}
- (BOOL) wantsCaseSensitiveSearch
{
return wantsCaseSensitiveSearch;
}
- inputTimeOut: (float) aFloat
{
inputTimeOut = aFloat;
return self;
}
- (float) inputTimeOut
{
return inputTimeOut;
}
//---------------------------------------------------------------------------------------------------------
// Event Handling
//---------------------------------------------------------------------------------------------------------
- mouseDown: (NXEvent*) theEvent
{
if ([self isEnabled] == NO) return self;
[super mouseDown: theEvent];
[[self window] makeFirstResponder: self] ;
return self;
}
- keyDown: (NXEvent *) theEvent
{
if ([self isEnabled] == NO) return self;
[self _removeTimedEntry];
switch (theEvent->data.key.charCode)
{
case UPARROW:
[self _upArrow: theEvent];
break;
case DOWNARROW:
[self _downArrow: theEvent];
break;
case LEFTARROW:
[self _leftArrow: theEvent];
break;
case RIGHTARROW:
[self _rightArrow: theEvent];
break;
case RETURN:
[self _return: theEvent];
break;
default:
if (theEvent->data.key.repeat) return self;
sprintf (searchString, "%s%c", searchString, theEvent->data.key.charCode);
if (! (strlen (searchString) % (CHUNK - 1))) [self _chunk];
[self _addTimedEntry];
break;
}
return self;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
//----------------------------------------------------------------------------------------------------
// Archiving Methods
//----------------------------------------------------------------------------------------------------
- read: (NXTypedStream*) stream
{
[super read: stream];
NXReadTypes (stream, "cf", &wantsCaseSensitiveSearch, &inputTimeOut);
return self;
}
- write: (NXTypedStream*) stream
{
[super write: stream];
NXWriteTypes (stream, "cf", &wantsCaseSensitiveSearch, &inputTimeOut);
return self;
}
- awake
{
[super awake];
[self _chunk];
memset (searchString, 0, CHUNK);
return self;
}
//----------------------------------------------------------------------------------------------------
// Superclass Overrides
//----------------------------------------------------------------------------------------------------
- acceptArrowKeys:(BOOL)acceptFlag andSendActionMessages:(BOOL)sendFlag
{
[super acceptArrowKeys:YES andSendActionMessages:sendFlag];
return self;
}
- acceptArrowKeys:(BOOL)acceptFlag
{
// 2.1 method.
[super acceptArrowKeys:YES andSendActionMessages:YES];
return self;
}
//---------------------------------------------------------------------------------------------------------
// IB Methods
//---------------------------------------------------------------------------------------------------------
- (const char*) getInspectorClassName
{
return "KeyDownBrowserInspector";
}
@end